﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpDwgDxfInterface.h"
#include "Color.h"
#include <map>

namespace gcmp
{
    class IFileImporterOptions;
    class IImportFileDocument;
    class IDocument;
    class IModelView;
    class IGraphicsPlane;
    class ILayerSettings;
    class ElementId;
    class Box3d;
    class Vector3d;
    class IDrawingProxyEntity;
    class IImportCustomizer;

    /// \brief 导入文件流类型
    enum class FileStreamType : int32_t
    {
        DWG_FILESTREAM = 0 ,        /// DWG/DXF文件流
        PDF_FILESTREAM = 1           /// PDF文件流
    };

    /// \brief 文件导入接口
    class GCMP_DWG_DXF_INTERFACE_EXPORT IFileImporter
    {
    public:
        virtual ~IFileImporter();

        /// \brief 创建文件导入器
        /// \param filePath 文件路径，.dxf（.dwg）格式创建cad文件导入器，.pdf格式创建pdf文件导入器（IPdfFileImporter）
        /// \param filePassword 文件密码，字符串为空说明没有密码
        /// 
        /// \return OwnerPtr<IFileImporter> 返回文件导入器
        static OwnerPtr<IFileImporter> Create(const std::wstring &filePath, const std::wstring& filePassword);

        /// \brief 创建文件流导入器
        /// \param pFileStream 字符数组指针
        /// \param length 字符数组长度
        /// \param fType 文件流类型(目前只支持dwg/dxf流类型)
        /// \param filePassword 文件密码，字符串为空说明没有密码
        /// 
        /// \return OwnerPtr<IFileImporter> 返回文件导入器
        static OwnerPtr<IFileImporter> Create(const char* pFileStream, int64_t length, FileStreamType fType, const std::wstring& filePassword);

        /// \brief 读取文件
        ///
        /// \return 是否读取成功 
        virtual bool ReadFile() = 0;

        /// \brief 以流方式导入文件(4G以上的超大文件不支持)
        ///
        /// \return 是否读取成功 
        virtual bool ReadFileByStream() = 0;                           

        /// \brief 获取文件导入选项
        ///
        /// \return 返回文件导入选项
        virtual IFileImporterOptions* GetFileImporterOptions() = 0;

        /// \brief 设置文件导入选项
        /// \param opFileImporterOptions 文件导入选项
        ///
        /// \return 
        virtual void SetFileImporterOptions(OwnerPtr<IFileImporterOptions> opFileImporterOptions) = 0;

        /// \brief 判断读取的文件是否为空文件
        ///
        /// \return 如果空返回true，否则false
        virtual bool IsFileEmpty() = 0;

        /// \brief 导入读取后的外部文件到文档中
        ///
        /// \param pDocument 文档
        /// \param pModelView 当前的视图窗口
        /// \return 返回导入文档后的构件Id, 在调用自动对齐或者手动对齐之前，构件不可见
        virtual ElementId ImportFile(IDocument* pDocument, const IModelView* pModelView, 
            std::wstring& errorMessage) = 0;

        /// \brief 自动动对齐导入的图纸构件
        ///
        /// \param pWorkPlane 需要把外部文件导入到的目标工作平面
        /// \return 返回是否成功对齐
        virtual bool AutoAlign(const IGraphicsPlane* pWorkPlane) = 0;

        /// \brief 手动对齐导入的图纸构件
        /// 
        /// \param pWorkPlane 需要把外部文件导入到的目标工作平面
        /// \param pickedPoint 手动对齐点
        /// \return 返回是否成功对齐
        virtual bool ManualAlign(const IGraphicsPlane* pWorkPlane, const Vector3d& pickedPoint) = 0;

        /// \brief 获取导入的CAD文件中的代理对象
        /// AutoCAD中由第三方插件创建的实体保存在代理对象中，通过此接口可获取代理对象元数据
        ///         
        /// \return 返回代理对象信息，如果没有则返回空的vector
        virtual const std::vector<const gcmp::IDrawingProxyEntity*> GetProxyEntities() const = 0;

        /// \brief 获取图纸的图层信息
        ///
        /// \return 返回图层信息，如果没有图层，则返回空的vector
        virtual const std::vector<OwnerPtr<ILayerSettings>>& GetLayerSettings() const = 0;

        /// \brief 设置需要导入的图层，图层id从GetLayerSettings()方法获取。如果没有设置，默认导入所有图层
        ///
        /// \param layerIds 需要导入的图层Id数组
        virtual bool SetLayersToImport(const std::vector<int>& layerIds) = 0;

        /// \brief 获得导入的文件中文字的无效字体（不包含大字体）
        /// 
        /// 该方法主要用于在ReadFile()后获得读取的文件中文字字体在目前程序中不支持显示的（无对应字体文件存在）
        /// \return 返回无效字体集
        virtual std::set<std::wstring> GetInvaildFonts() const = 0;

        /// \brief 更新导入文件中的无效字体
        /// 
        /// 该方法主要用于在ReadFile()后通过GetInvaildFonts()后对无效的字体自定义的进行更新(重新设置有效的字体)，需要在ReadFile()之后,ImportFile()之前使用
        /// \param invaildFontsToNewFonts 其中key是通过GetInvaildFonts获得的无效字体，value是该无效字体需要更新的字体（若该value的字体还是无效，则默认采用宋体显示）
        /// \return 返回是否更新成功
        virtual bool UpdateInvaildFonts(const std::map<std::wstring, std::wstring>& invaildFontsToNewFonts) = 0;

        /// \brief 获得导入的文件中文字的无效的大字体
        /// 
        /// 该方法主要用于在ReadFile()后获得读取的文件中文字字体在目前程序中不支持显示的（无对应字体文件存在）
        /// \return 返回无效大字体集
        virtual std::set<std::wstring> GetInvaildBigFonts() const = 0;

        /// \brief 更新导入文件中的无效大字体
        /// 
        /// 该方法主要用于在ReadFile()后通过GetInvaildBigFonts()后对无效的大字体自定义的进行更新(重新设置有效的字体)，需要在ReadFile()之后,ImportFile()之前使用
        /// \param invaildBigFontsToNewFonts 其中key是通过GetInvaildBigFonts获得的无效大字体，value是该无效字体需要更新的字体
        /// \return 返回是否更新成功
        virtual bool UpdateInvaildBigFonts(const std::map<std::wstring, std::wstring>& invaildBigFontsToNewFonts) = 0;

        /// \brief 设置字体替换表
        /// 
        /// 该方法主要用于在ReadFile()后通过SetReplaceFonts()设置字体替换表
        /// \param withPlatformDefault 是否保留平台默认值
        /// \param replaceFontMap 其中key是无效字体，value是替换字体
        /// \return 返回是否更新成功
        virtual bool SetReplaceFonts(bool withPlatformDefault,std::map<std::wstring, std::wstring>* replaceFontMap) = 0;


        /// \brief 设置导入自定义回调
        ///
        /// \param opImportCustomizerack 用户自定义导入
        /// \return 设置成功返回true，失败返回false
        virtual bool SetImportCustomizer(OwnerPtr<IImportCustomizer> opImportCustomizer) = 0;
    };

    /// \brief pdf文件导入接口
    class GCMP_DWG_DXF_INTERFACE_EXPORT IPdfFileImporter : public IFileImporter
    {
    public:
        virtual ~IPdfFileImporter();

        /// \brief 预览获取pdf文件页面总数
        /// 
        /// \return 返回pdf文件页面总数
        virtual int PreviewPageItemCount() = 0;
    };
}

